home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-07-06 | 18.1 KB | 433 lines | [TEXT/CCL ] |
-
- ;=====================================================================
- ;
- ; GPC Editor
- ;
- ; Name: ken-objects.lisp
- ;
- ; Various objects used in the GPC Editor.
- ;
- ;---------------------------------------------------------------------
- ; Date Name Comments
- ;---------------------------------------------------------------------
- ; 10/13/88 lhh Initial Documentation
- ;=====================================================================
-
- ;;; load this file into the objects available for the system.
- ;;; ???
- ;;; Why is the statement 'in-package' needed
- ;;;???
-
- (provide "ken-objects")
- (in-package "ken-objects")
-
- ;;; Shadow nothing.
- (export '(*alist-dialog-item* cell-contents full-cell-contents value-cell-contents
- *pane* *paned-window*
- *selection-dialog* ))
-
- ;;; Require nothing.
- (use 'ccl)
- ;;; Import nothing.
-
-
- ;;;;****************************************************************************
- ;;;; The Actual Contents
- ;;;;****************************************************************************
-
- ;;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;;;; *alist-dialog-item*
- ;;;; A kind of *sequence-dialog-item* that supports displaying alists.
- ;;;;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- (defobject *alist-dialog-item* *sequence-dialog-item*)
-
- (defobfun (cell-contents *alist-dialog-item*) (cell)
- (car (usual-cell-contents cell)))
-
- (defobfun (full-cell-contents *alist-dialog-item*) (cell)
- (elt (table-sequence) (cell-to-index cell)))
-
- (defobfun (value-cell-contents *alist-dialog-item*) (cell)
- (cdr (full-cell-contents cell)))
-
- #| 11/13/87 unfinished
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;+++ *size-it-window* - UNFINISHED AS OF 11/13/87
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- #|
- size-it-window is a subclass of *window* which allows the user to size and
- position the window on creation (NOT appearance) with the mouse. When asked
- to exist if
- option-key is depressed then use user mouse input to position
- and size the window
- command-key is depressed then use user mouse input to position
- and size the window and store these
- globally for this class of window
- otherwise if
- size and/or position is given use these
- otherwise if
- global defaults (see command-key) use these
- for this class are given
- otherwise use *window* defaults
-
- The work of maintaining the global list of defaults is done by function exist.
- |#
-
- (setq *size-it-defaults* '())
-
- (defobject *size-it-window* *window*)
-
- (defobfun (exist *size-it-window*) (&rest init-list)
- (let* ((window-type (getf init-list :window-type :document))
- (given-pos (getf init-list :window-pos '()))
- (given-size (getf init-list :window-size '()))
- (class-defaults (assoc (ask (car (object-parents (self))) object-name)
- *size-it-defaults*))
- (global-defaults '(#@(6 44) #@(502 150)))
- (defaults (list (cond (given-pos)
- ((car class-defaults))
- (t (car global-defaults)))
- (cond (given-size)
- ((cadr class-defaults))
- (t (cadr global-defaults)))))
- (settings (cond ((option-key-p) (get-settings defaults window-type))
- ((command-key-p) (set-class-defaults
- (get-settings defaults window-type)))
- (t defaults))))
- (usual-exist
- (init-list-default init-list
- :window-position (car settings)
- :window-size (cadr settings)))))
-
- (defobfun (get-settings *size-it-window*) (defaults window-type)
- (with-cursor 2
- (let ((default-pos (car defaults))
- (default-size (cadr defaults))
- (start (loop (when (mouse-down-p)
- (return (local-to-global
- (ask (front-window)
- (window-mouse-position)))))))
- (end (loop (when (not (mouse-down-p))
- (return (local-to-global
- (ask (front-window)
- (window-mouse-position))))))))
- (if (double-click-spacing-p start end)
- (adjust-window-settings (list (start default-size))
- window-type)
- (adjust-window-settings (list (start (subtract-points end start)))
- window-type)))))
-
- (setq w (oneof *size-it-window*))
- |# 11/13/87 unfinished
-
-
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;+++ *paned-window*
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- #|
- Paned windows organize a set of windows so that all may be activated, deactivated,
- selected, and closed at once. Panes can be any window object but :document-with-
- grow and :document-with-zoom, since changing the size of a pane is not yet
- supported. Also, overlapping of panes is not checked yet either, so WATCH OUT!
-
- |#
-
- (defobject *pane* *window*)
- (defobfun (exist *pane*) (init-list)
- (declare (special *paned-window*))
- (let ((my-window (getf init-list :my-window nil))
- (window-type (getf init-list :window-type :document)))
- (cond ((equal window-type :document-with-zoom)
- (error "Panes may not be of type :document-with-zoom."))
- ((equal window-type :document-with-grow)
- (error "Panes may not be of type :document-with-grow."))
- ((and my-window (not (typep my-window *paned-window*)))
- (error ":my-window ~a must be a *paned-window*." my-window))
- (t (have 'my-window my-window)
- (usual-exist
- (init-list-default init-list
- :window-show nil))))))
- (defobfun (window-select-event-handler *pane*) ()
- (if (null my-window)
- (usual-window-select-event-handler)
- (ask my-window (window-select-event-handler))))
- (defobfun (window-close *pane*) ()
- (if (null my-window)
- (usual-window-close)
- (ask my-window (window-close))))
- (defobfun (window-deactivate-event-handler *pane*) ()
- (if (null my-window)
- (usual-window-deactivate-event-handler)
- (ask my-window (window-deactivate-event-handler))))
- (defobfun (window-activate-event-handler *pane*) ()
- (if (null my-window)
- (usual-window-activate-event-handler)
- (ask my-window (window-activate-event-handler))))
-
-
- (defobject *paned-window* *window*)
- (defobfun (exist *paned-window*) (init-list)
- (declare (special *pane*))
- (let ((panes (getf init-list :panes '())))
- (have 'panes (cond
- ((null panes) '())
- ((notevery #'(lambda (thing) (typep thing *pane*)) panes)
- (error "All panes must inherit from ~a." *pane*))
- (t (muliple-value-bind
- (check msg)
- (ok-regions-p
- (mapcar #'(lambda (p)
- (ask p
- (unless (ownp 'wptr)
- (exist))))
- panes))
- (if check panes (error msg))))))
- (usual-exist
- (init-list-default init-list
- :window-show nil))))
- (defobfun (add-panes *paned-window*) (&rest the-panes)
- (declare (special *pane*))
- (let ((w (self)))
- (if (and (mapc #'(lambda (p) (typep p *pane*)) the-panes)
- (ok-regions-p (append (mapcar #'(lambda (p)
- (ask p
- (unless (ownp 'wptr)
- (exist))))
- the-panes)
- panes)))
- (mapcar #'(lambda (p)
- (ask p (setf my-window w))
- (ask w (pushnew p panes)))
- the-panes)
- (error "All panes, even ~a, must inherit from ~a."
- p
- *pane*))))
-
-
- ;;; window-select-event-handler shadows the default handler, which would
- ;;; deactivate all the panes. This version activates all the panes and
- ;;; moves them as a block to the front of the window list.
- ;
- (defobfun (window-select-event-handler *paned-window*) ()
- (unless (find (front-window) panes)
- (ask (front-window) (window-deactivate-event-handler))
- (window-activate-event-handler)))
-
- ;;; window-activate-event-handler shadows the default handler, which would
- ;;; ignore the window panes. This version activates all panes as well.
- ;
- (defobfun (window-activate-event-handler *paned-window*) ()
- (do ((counter 0 (1+ counter)))
- ((= (length panes) counter)
- (progn
- (_hilitewindow :ptr wptr :word #xFFFF)
- (usual-window-activate-event-handler)))
- (ask (nth counter panes)
- (_hilitewindow :ptr wptr :word #xFFFF)
- (usual-window-activate-event-handler)
- (set-window-layer counter))))
-
- ;;; window-deactivate-event-handler shadows the default handler, which would
- ;;; ignore the window panes. This version deactivates all panes as well.
- ;
- (defobfun (window-deactivate-event-handler *paned-window*) ()
- (do ((counter (length panes) (1- counter)))
- ((= 0 counter) (usual-window-deactivate-event-handler))
- (ask (nth counter panes)
- (usual-window-deactivate-event-handler))))
-
- ;;; window-close shadows the default window-close, which would
- ;;; ignore the window panes. This version closes all panes as well.
- ;
- (defobfun (window-close *paned-window*) ()
- (do ((counter (length panes) (1- counter)))
- ((= 0 counter) (usual-window-close))
- (ask (nth counter panes)
- (usual-window-close))))
-
- ;;; make-paned-window takes a window and a list of panes. It remakes (if nec.)
- ;;; the window as a *paned-window* with the given list of panes (also remade
- ;;; as *pane*'s, if nec.) as its panes, checking that the rectangles of all
- ;;; of the panes do not overlap, and the union of all the rectangles lies
- ;;; within the window's content region.
- ;
- (defobfun (ok-regions-p *window*) (panes)
- (let ((scratch-region (new-region))
- (the-union (new-region)))
- (set-empty-region the-union)
- (do ((counter (1- (length panes)) (1- counter)))
- ((= -1 counter)
- (if (empty-region-p
- (difference-region the-union
- (rref wptr window.contrgn)
- scratch-region))
- (progn
- (dispose-region scratch-region)
- (dispose-region the-union)
- (values t nil)
- (progn
- (dispose-region scratch-region)
- (dispose-region the-union)
- (values nil
- (format nil
- "The panes must all be within ~a's content region."
- (self)))))))
- (ask (nth counter panes)
- (if (not
- (empty-region-p
- (intersect-region the-union
- (rref wptr window.strucrgn)
- scratch-region)))
- (progn
- (dispose-region scratch-region)
- (dispose-region the-union)
- (values nil "The panes may not overlap."))
- (copy-region
- (union-region the-union
- (rref wptr window.strucrgn)
- scratch-region)
- the-union))))))
-
- (defun make-paned-window (window &rest panes)
- (declare (special *paned-window*))
- (when (ask window (ok-regions-p panes))
- (ask
- (unless (typep window *paned-window*)
- (apply #'remake-object window
- *paned-window*
- (object-parents window)))
- (have 'panes
- (mapcar #'(lambda (w) (make-pane w window)) panes)))
- window))
-
-
- #|
- *selection-dialog*
-
- Selection dialogs contain a prompt, a table, an ok-button, and a cancel-button.
-
- The function GET-SELECTION is used to create selection dialogs. The user makes
- a selection in the table and presses either button. If ok-button is pressed,
- then the selection is returned. If cancel-button is pressed, then :cancel is
- returned.
-
- Selection dialogs are always modal. Therefore, if cancel-button is pressed,
- a throw to :cancel will be made, with :cancel returned. Unless GET-SELECTION
- is called from withing a catch form, the throw will continue to the Listener.
-
- GET-SELECTION accepts any even number of arguments. The arguments should
- alternate between keywords and values (like the argument to oneof). GET-
- SELECTION accepts the standard window init-list options, but you usually
- need supply only :window-title. In addition, GET-SELECTION accepts the
- following pseudo-keyword arguments:
-
- :prompt The prompt string to display in the dialog.
-
- :item-list A list of items to display in the dialog.
-
- :table-height The height of the selection table defaults to 4
- unless this keyword and value are given. The value
- should be an integer number of CELLS.
-
- :dialog-width The width of the dialog is not computed automatically.
- The default width is 200 pixels. Specify a different
- width using :dialog-width. It should be an integer
- number of PIXELS.
-
- :position The upper right corner of the dialog defaults to #@(100 50).
- unless this keyword and value are given. The value
- should be a POINT, ie of the form #@(... ...).
-
- :|#
-
- (defobject *selection-dialog* *dialog*)
-
- (defobfun (exist *selection-dialog*) (&rest init-list)
- (declare (special *screen-height* *screen-width*)
- (special *button-dialog-item* *sequence-dialog-item*
- *static-text-dialog-item*))
- (let* ((item-list (getf init-list :item-list ()))
- (list-length (length item-list))
- (table-height (* 16 (min (- *screen-height* 122)
- (getf init-list :table-height 4))))
- (dialog-height (+ 56 table-height))
- (dialog-width (max 150 (getf init-list :dialog-width 150)))
- (dialog-position (getf init-list :position #@(100 50)))
- (prompt (getf init-list :prompt "Select one and press OK:"))
- (the-prompt (oneof *static-text-dialog-item*
- :dialog-item-position #@(1 1)
- :dialog-item-text prompt))
- (ok-button (oneof *button-dialog-item*
- :dialog-item-position (make-point
- (- dialog-width 39)
- (- dialog-height 20))
- :dialog-item-text " OK "
- :dialog-item-enabled-p nil))
- (the-table (oneof *sequence-dialog-item*
- :dialog-item-position #@(1 19)
- :table-sequence item-list
- :table-vscrollp t
- :table-hscrollp nil
- :dialog-item-size (make-point
- (- dialog-width 2)
- table-height)
- :cell-size (make-point
- (- dialog-width 19)
- 16)
- :dialog-item-action
- (nfunction
- dialog-item-action
- (lambda ()
- (ask ok-button
- (unless (dialog-item-enabled-p)
- (dialog-item-enable)))
- (ask my-dialog (set-default-button ok-button))
- (usual-dialog-item-action)))))
- (cancel-button (oneof *button-dialog-item*
- :dialog-item-position (make-point
- 4
- (- dialog-height 20))
- :dialog-item-text " Cancel "
- :dialog-item-action
- (nfunction
- dialog-item-action
- (lambda ()
- (usual-dialog-item-action)
- (return-from-modal-dialog :cancel))))))
- (ask ok-button (fhave 'dialog-item-action
- (nfunction
- dialog-item-action
- (lambda ()
- (usual-dialog-item-action)
- (return-from-modal-dialog
- (ask the-table
- (cell-contents (car (selected-cells)))))))))
- (usual-exist
- (init-list-default init-list
- :window-type :double-edge-box
- :window-size (make-point dialog-width dialog-height)
- :window-position dialog-position
- :window-show t
- :window-title (getf init-list
- :window-title "Select")
- :dialog-items (list the-table the-prompt cancel-button
- ok-button)))))
-
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;+++ get-object-descendants
- ;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
- ;
- ; This function recursively finds the descendants of its argument.
- ; Of course it only works for hierarchies created using defobject.
- ;
- (defun get-object-descendants (thing)
- (let ((kids (ask thing object-children)))
- (when kids
- (nconc (mapcar '(lambda (thing)
- (ask thing object-name))
- kids)
- (apply #'nconc
- (mapcar #'get-object-descendants
- kids))))))
-